home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1994 October / Macformat17.cdr / Shareware City / AfterDark / SimAcid folder / simacid.c < prev    next >
Text File  |  1993-09-13  |  7KB  |  246 lines

  1. /* simacid.c
  2.  *
  3.  * An After Dark module by Tristan Farnon, Robert George, and Harrison Page
  4.  * 
  5.  * Melt - by Tristan Farnon                     (tristan@west.darkside.com)
  6.  * Ripple - by Robert George                    (rgeorge@mv.us.adobe.com)
  7.  * After Dark module and Bad - by Harrison Page (harrison@wiretap.spies.com)
  8.  *
  9.  * v1.0 –     pop-up menu to select your trip (Melt, Ripple) added
  10.  *            checkbox "James is helping?" makes James' characteristic moaning sounds when enabled
  11.  *            module's credits box features James in all his glory
  12.  *          support for all screen sizes based on monitorRect
  13.  *
  14.  * v1.1 –     removed all that extra garbage left over from Bouncing Ball
  15.  *            added another trip (Bad) that inverts rects some of the time
  16.  *            changed NUM_LOOPS from 500 to 350 - better abort response
  17.  *            James only moans 10% of the time now
  18.  *            
  19.  * to do –     support for multiple monitors - melt or blank the other one out?
  20.  *            James should make more noises
  21.  *            adjustable speed of [melting,ripple]
  22.  *          long pause to abort in Demo mode rather annoying 
  23.  */
  24.  
  25. #include <QuickDraw.h>
  26. #include <Memory.h>
  27. #include <Resources.h>
  28. #include <OSUtils.h>
  29. #include <ToolUtils.h>
  30. #include <FixMath.h>
  31. #include <Picker.h>
  32.  
  33. #include "GraphicsModule_Types.h"
  34. #include "Sounds.h"
  35. #include "simacid.h"
  36.  
  37. OSErr DoInitialize (Handle *storage, RgnHandle blankRgn, GMParamBlockPtr params)
  38.     {
  39.     OSErr result;
  40.     short i;
  41.     Handle h;
  42.     AcidStoragePtr acidStorage;
  43.     Rect monitorRect;
  44.     StringPtr errorMessage = (StringPtr)"\pSimAcid failed – you got burned.";
  45.         
  46.     /* in case we have an error, this message will be displayed. */
  47.     BlockMove(errorMessage, params->errorMessage, 1 + errorMessage[0]);
  48.     
  49.     h = NewHandleClear(sizeof(AcidStorage));        /* allocate handle to my storage */
  50.     FailNIL(h);
  51.     
  52.     *storage = h;     /* store a reference to our storage where After Dark™ can keep it. */
  53.  
  54.     MoveHHi(h);        /* lock down our storage so we can refer to it by pointer. */
  55.     HLock(h);    
  56.     acidStorage = (AcidStoragePtr)*h;    
  57.     
  58.     /* see if a sound channel is even part of the parameter block. */
  59.     acidStorage->soundAvailable = (params->systemConfig & SoundAvailable) != 0;
  60.     
  61.     if(acidStorage->soundAvailable)
  62.         {
  63.         /* load the resources for our sounds. */
  64.         
  65.         acidStorage->jamesSound = GetResource('snd ', JAMES_MOAN);
  66.         FailNIL(acidStorage->jamesSound);
  67.         
  68.         /* get ready to use sound. */
  69.         acidStorage->soundInfo = OpenSound();
  70.         }
  71.  
  72.     /* unlock storage handle. */    
  73.     HUnlock(h);
  74.  
  75.     return noErr;
  76.     }
  77.  
  78. static void CleanUp (AcidStorage** storage)
  79.     {
  80.     if (storage) 
  81.         {
  82.         AcidStorage *acidStorage;
  83.         
  84.         HLock ((Handle) storage);
  85.         acidStorage = *storage;
  86.  
  87.         if (acidStorage->soundAvailable)     /* free the sounds! */
  88.             if (acidStorage->jamesSound)
  89.                 ReleaseResource (acidStorage->jamesSound);
  90.  
  91.         DisposHandle ((Handle) storage);
  92.         }
  93.     }
  94.  
  95. OSErr DoBlank(Handle storage, RgnHandle blankRgn, GMParamBlockPtr params)
  96.     {
  97.     return noErr;
  98.     }
  99.  
  100. OSErr DoDrawFrame (Handle storage, RgnHandle blankRgn, GMParamBlockPtr params)
  101.     {
  102.     register     AcidStoragePtr acidStorage;    /* to hold dereferenced storage handle */
  103.     Rect         monitorRect;                /* rectange of monitor */
  104.     Rect           rip;                        /* current rect */
  105.     short       scrollType;                    /* type of window scroll (see switch below) */
  106.     short        jamesRandom;                /* to check whether james is helping this time */
  107.     int         howOften;
  108.     int         controlJamesEnabled;        /* whether james is helping via AD panel */
  109.     int         controlTripType;            /* what kind of trip we're on */
  110.     int         j;            
  111.     int         count;
  112.     int            moveHere = 2;                /* generic values */
  113.     int         moveThere = -2;
  114.     int            howBad = 50;                /* how often to invert a rect */
  115.   
  116.     HLock(storage);
  117.     acidStorage = (AcidStoragePtr) *storage;
  118.     
  119.     monitorRect = params->monitors->monitorList[0].bounds;
  120.     controlTripType = params->controlValues[0];            /* 0 = pop-up for type of trip */
  121.     controlJamesEnabled = params->controlValues[1];        /* 1 = whether james is helping */
  122.     
  123.     howOften = JAMES_RARELY;                            /* for testing purposes */
  124.     jamesRandom = RangedRdm(1, JAMES_ZENITH);            /* pick a random number */
  125.     
  126.     /* if howOften is greater than the random number between 1 and 1000, moan. */
  127.     
  128.     if (controlJamesEnabled)
  129.         if ((jamesRandom > howOften) && (acidStorage->soundAvailable))
  130.             PlaySound (acidStorage->soundInfo, params->sndChannel, acidStorage->jamesSound);
  131.  
  132.     for (j = 0, count = 0; j <= NUM_LOOPS; j++)
  133.         {
  134.         rip = ObtainRect (&monitorRect);                // get a rectangle
  135.         
  136.         switch (controlTripType)                        // set up trip type */
  137.             {
  138.             case TRIP_MELTING:
  139.                 scrollType = 1;                            // tristan's melt - only move downward */
  140.                 break;
  141.                 
  142.             case TRIP_RIPPLE:
  143.                 scrollType = RangedRdm(1, 5);            // bob's ripple - move every which way */
  144.                 break;
  145.                 
  146.             case TRIP_BAD:
  147.                 scrollType = RangedRdm(1, 5);
  148.                 moveHere = 10;
  149.                 moveThere = -10;
  150.                 howBad = 200;
  151.                 break;                
  152.             }
  153.             
  154.         switch (scrollType)
  155.             {
  156.             case 1:
  157.                 ScrollRect (&rip, 0, moveHere, nil);
  158.                 if (controlTripType == TRIP_BAD)
  159.                     ScrollRect (&rip, 0, moveThere, nil);
  160.                 break;
  161.             
  162.             case 2:
  163.                 ScrollRect (&rip, 0, moveThere, nil);
  164.                 if (controlTripType == TRIP_BAD)
  165.                      ScrollRect (&rip, 0, moveHere, nil);
  166.                 break;
  167.             
  168.             case 3:
  169.                 ScrollRect (&rip, moveHere, 0, nil);
  170.                 if (controlTripType == TRIP_BAD)
  171.                     ScrollRect (&rip, moveThere, 0, nil);
  172.                 break;
  173.                 
  174.             case 4:
  175.                 ScrollRect (&rip, moveThere, 0, nil);
  176.                 if (controlTripType == TRIP_BAD)
  177.                     ScrollRect (&rip, moveHere, 0, nil);
  178.                 break;
  179.             }
  180.             
  181.         if (!(++count % howBad))
  182.             if (controlTripType == TRIP_BAD)
  183.                 InvertRect (&rip);
  184.         }
  185.  
  186.     HUnlock(storage);
  187.  
  188.     return noErr;
  189. }
  190.  
  191. OSErr DoClose (storage, blankRgn, params)
  192. Handle storage;
  193. RgnHandle blankRgn;
  194. GMParamBlockPtr params;
  195. {
  196.     AcidStorage **acidStorage = (AcidStorage**) storage;
  197.  
  198.     if(acidStorage) 
  199.         CloseSound((**acidStorage).soundInfo, params->sndChannel);
  200.  
  201.     /* deallocate our storage */
  202.     CleanUp(acidStorage);
  203.  
  204.     return noErr;
  205. }
  206.  
  207. OSErr DoSetUp(blankRgn, message, params)
  208.     RgnHandle blankRgn;
  209.     short message;
  210.     GMParamBlockPtr params;
  211.     {
  212.  
  213.     switch(message) 
  214.         {
  215.         default:
  216.             SysBeep(1);
  217.             break;
  218.         }
  219.     return noErr;
  220.     }
  221.  
  222. /* utility functions. */
  223.  
  224. Rect    ObtainRect (Rect *monitorRect)
  225. {
  226.         static Rect SetUpRect;
  227.         
  228.         SetUpRect.top = RangedRdm  (monitorRect->top, monitorRect->bottom);
  229.         SetUpRect.left = RangedRdm (monitorRect->left, monitorRect->right);
  230.         SetUpRect.bottom = RangedRdm (monitorRect->top, monitorRect->bottom);
  231.         SetUpRect.right = RangedRdm (monitorRect->left, monitorRect->right);
  232.         
  233.         return (SetUpRect);
  234. }
  235.  
  236.  
  237. unsigned short RangedRdm( unsigned short min, unsigned short max )
  238. {
  239.         unsigned        qdRdm;  
  240.         long            range, t;
  241.  
  242.         qdRdm = Random();
  243.         range = max - min;
  244.         t = (qdRdm * range) / 65536; 
  245.         return( t+min );
  246. }